#include "updatewidget.h"
#include "ui_updatewidget.h"
#include <QPainterPath>
#define PANEL_DBUS_SERVICE "com.ukui.panel.desktop"
#define PANEL_DBUS_PATH "/"
#define PANEL_DBUS_INTERFACE "com.ukui.panel.desktop"
#define UKUI_PANEL_SETTING "org.ukui.panel.settings"

#define DBUS_NAME       "org.ukui.SettingsDaemon"
#define DBUS_PATH       "/org/ukui/SettingsDaemon/wayland"
#define DBUS_INTERFACE  "org.ukui.SettingsDaemon.wayland"

updatewidget::updatewidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Form)
{
    ui->setupUi(this);
    //设置出现在屏幕的位置以及大小
    listenPanelChange();
    QString xdg_session_type = qgetenv("XDG_SESSION_TYPE");
    if (xdg_session_type != "wayland"){
        initPanelDbusGsetting();
        GetsAvailableAreaScreen();
        qDebug()<<"not wayland";
    } else {
        //注释掉的是原先的接口，已经废除。采用原本的获取方式
//        initset_window_position();
//        set_window_position();
        initPanelDbusGsetting();
        GetsAvailableAreaScreen();
        qDebug()<<"wayland";
    }

    //设置任务栏无显示
    setWindowFlags(Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint);
    setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);

    update_lab     = new QLabel();
    tip_lab        = new QLabel();
    tip_lab->setText(tr("at"));
    tip_lab1 = new QLabel();
    tip_lab1->setText(tr("No reminders"));
    agreebtn       = new QPushButton();
    disagreebtn    = new QPushButton();

    m_pfirstlayout  = new QVBoxLayout();
    m_labellayout = new QHBoxLayout();
    m_psecondlayout = new QHBoxLayout();
    m_pselectlayout = new QHBoxLayout();

    comboBox = new QComboBox();
    comboBox->clear();
    strList<<tr("In 30 minutes")<<tr("three hours later")<<tr("one day later");
    comboBox->addItems(strList);

    labelwidget = new QWidget();
    statwidget = new QWidget();
    selectWidget = new QWidget();

    agreebtn->setText(tr("Update"));
    disagreebtn->setText(tr("Delay"));

    connect(agreebtn,&QPushButton::clicked,this,&updatewidget::agreeBtnClicked);
    connect(disagreebtn,&QPushButton::clicked,this,&updatewidget::disAgreeBtnClicked);


    m_labellayout->addWidget(update_lab);
    labelwidget->setLayout(m_labellayout);

    m_pselectlayout->addWidget(tip_lab);
    m_pselectlayout->addWidget(comboBox);
    m_pselectlayout->addWidget(tip_lab1);
    m_pselectlayout->addStretch();
    selectWidget->setLayout(m_pselectlayout);


    m_psecondlayout->addWidget(disagreebtn);
    m_psecondlayout->addWidget(agreebtn);
    statwidget->setLayout(m_psecondlayout);

    m_pfirstlayout->addWidget(labelwidget);
    m_pfirstlayout->addWidget(selectWidget);
    m_pfirstlayout->addWidget(statwidget);
    this->setLayout(m_pfirstlayout);
    this->setAttribute(Qt::WA_TranslucentBackground);
    this->setFixedSize(330,180);

}

updatewidget::~updatewidget()
{
    delete ui;
}

/**
 * @brief updatewidget::initPanelDbusGsetting
 * 初始化与任务栏gsetting和dbus
 */
void updatewidget::initPanelDbusGsetting()
{
    /* 链接任务栏Dbus接口，获取任务栏高度和位置 */
    m_pServiceInterface = new QDBusInterface(PANEL_DBUS_SERVICE, PANEL_DBUS_PATH, PANEL_DBUS_INTERFACE, QDBusConnection::sessionBus());
    m_pServiceInterface->setTimeout(2147483647);
    connect(m_pPanelSetting, &QGSettings::changed,[=](QString key){
        if ("panelposition" == key | "panelsize" == key) {
             GetsAvailableAreaScreen();
        }
     });
}

void updatewidget::listenPanelChange()
{
    /* 链接任务栏dgsetting接口 */
    if(QGSettings::isSchemaInstalled(UKUI_PANEL_SETTING))
        m_pPanelSetting = new QGSettings(UKUI_PANEL_SETTING);
}

/**
 * @brief updatewidget::connectTaskBarDbus
 * 链接任务栏dbus获取高度的接口
 * @return
 */
int updatewidget::connectTaskBarDbus()
{
    int panelHeight = 46;
    if (m_pPanelSetting != nullptr) {
        QStringList keys = m_pPanelSetting->keys();
        if (keys.contains("panelsize")) {
            panelHeight = m_pPanelSetting->get("panelsize").toInt();
        }
    } else {
        QDBusMessage msg = m_pServiceInterface->call("GetPanelSize", QVariant("Hight"));
        panelHeight = msg.arguments().at(0).toInt();
        return panelHeight;
    }
    return panelHeight;
}

/**
 * @brief updatewidget::getPanelSite
 * 获取任务栏状态位置下上左右
 * @return
 * 返回任务栏位置
 */
int updatewidget::getPanelSite()
{
    int panelPosition = 0;
    if (m_pPanelSetting != nullptr) {
        QStringList keys = m_pPanelSetting->keys();
        if (keys.contains("panelposition")) {
            panelPosition = m_pPanelSetting->get("panelposition").toInt();
        }
    } else {
        QDBusMessage msg = m_pServiceInterface->call("GetPanelPosition", QVariant("Site"));
        panelPosition = msg.arguments().at(0).toInt();
    }
    qDebug() << "Current Position of ukui panel: " << panelPosition;
    return panelPosition;
}

/**
 * @brief updatewidget::GetsAvailableAreaScreen
 * 获取屏幕的可用区域高度和宽度并设置位置
 */
void updatewidget::GetsAvailableAreaScreen()
{
    //如果取不到任务栏的高度,还是优先获取桌面分辨率,可用区域
    if ((0 == connectTaskBarDbus()) && (0 == getPanelSite())) {
        QScreen* pScreen = QGuiApplication::primaryScreen();
        QRect DeskSize = pScreen->availableGeometry();
        m_nScreenWidth = DeskSize.width();                      //桌面分辨率的宽
        m_nScreenHeight = DeskSize.height();                    //桌面分辨率的高
    } else {
        //如果取到任务栏的高度,则取屏幕分辨率的高度
        int h = connectTaskBarDbus();
        QRect screenRect = QGuiApplication::primaryScreen()->geometry();
        m_nScreenWidth = screenRect.width();
        m_nScreenHeight = screenRect.height();
        m_pPeonySite = getPanelSite();
        switch (m_pPeonySite)
        {
            case updatewidget::PanelDown :
                {
                    this->setGeometry(m_nScreenWidth - 340,m_nScreenHeight - h - 190,300,150-100);
                    qDebug()<<"Taskbar coordinates: [ '"<<m_nScreenWidth-340<<"','"<< m_nScreenHeight-h-190<<"','"<<300<<"','"<<150 - 100<<"']";
                }
                break;
            case updatewidget::PanelUp:
                {
                    this->setGeometry(m_nScreenWidth - 340,m_nScreenHeight - 190,300,150-100);
                    qDebug()<<"任务栏在上方： 显示坐标为： "<<m_nScreenWidth - 340 << m_nScreenHeight - 190 << 300 << 150 - 100;
                }
                break;
            case updatewidget::PanelLeft:
                {
                    this->setGeometry(m_nScreenWidth - 340,m_nScreenHeight - 190,300,150-100);
                    qDebug()<<"任务栏在左侧： 显示坐标为： "<<m_nScreenWidth - 340 << m_nScreenHeight - 190 << 300 << 150 - 100;
                }
                break;
            case updatewidget::PanelRight:
                {
                    this->setGeometry(m_nScreenWidth - 340 - h,m_nScreenHeight - 190,300,150-100);
                    qDebug()<<"任务栏在右侧： 显示坐标为： "<<m_nScreenWidth - 340 - h << m_nScreenHeight - 190 << 300 << 150 - 100;
                }
                break;
            default:
                break;
        }

    }
    qDebug() << "Current screen width:  " << m_nScreenWidth <<";  height:"<< m_nScreenHeight;
}


int updatewidget::getTaskbarPos(QString str)
{
    QDBusInterface interface( "com.ukui.panel.desktop",
                              "/",
                              "com.ukui.panel.desktop",
                              QDBusConnection::sessionBus() );

    QDBusReply<int> reply = interface.call("GetPanelPosition", str);
    return reply;
}

int updatewidget::getTaskbarHeight(QString str)
{
    QDBusInterface interface( "com.ukui.panel.desktop",
                              "/",
                              "com.ukui.panel.desktop",
                              QDBusConnection::sessionBus() );

    QDBusReply<int> reply = interface.call("GetPanelSize", str);
    return reply;
}


int updatewidget::getScreenGeometry(QString methodName)
{
    int res = 0;
    QDBusMessage message = QDBusMessage::createMethodCall(DBUS_NAME,
                               DBUS_PATH,
                               DBUS_INTERFACE,
                               methodName);
    QDBusMessage response = QDBusConnection::sessionBus().call(message);
    if (response.type() == QDBusMessage::ReplyMessage) {
        if(response.arguments().isEmpty() == false) {
            int value = response.arguments().takeFirst().toInt();
            res = value;
        }
    } else {
        qDebug()<<methodName<<"called failed";
    }
    return res;
}

void updatewidget::initset_window_position()
{
    connect(m_pPanelSetting, &QGSettings::changed,[=](QString key){
        if ("panelposition" == key | "panelsize" == key) {
             set_window_position();
        }
     }
    );
}

void updatewidget::set_window_position()
{
    QRect rect;
    int availableWidth,totalWidth;
    int availableHeight,totalHeight;
    rect = this->geometry();
    int priX = getScreenGeometry("x");
    int priY = getScreenGeometry("y");
    int priWid = getScreenGeometry("width");
    int priHei = getScreenGeometry("height");
    QRect screenGeometry = qApp->primaryScreen()->geometry();

    availableWidth = priX + priWid;
    availableHeight = priY + priHei;
    totalHeight = screenGeometry.height();
    totalWidth = screenGeometry.width();

    int distance = 4;
    int n = 0;
    int m = 46;

    n = getTaskbarPos("position");
    m = getTaskbarHeight("height");
    if(n == 0){
        //任务栏在下侧
        this->setGeometry(priWid-330-distance,availableHeight-180-m-distance,this->width(),this->height());
        qDebug()<<"任务栏在下侧"<<priWid-330-distance<<"  "<<availableHeight-180-m-distance <<" "<<this->width()<<" "<<this->height();
    }else if(n == 1){
        //任务栏在上侧
        this->setGeometry(priWid-330-distance,availableHeight-180-distance,this->width(),this->height());
        qDebug()<<"任务栏在上侧"<<priWid-330-distance<<"  "<<availableHeight-180-distance <<" "<<this->width()<<" "<<this->height();
    } else if (n == 2){
        //任务栏在左侧
        this->setGeometry(priWid-330-distance,availableHeight-180-distance,this->width(),this->height());
        qDebug()<<"任务栏在左侧"<<priWid-330-distance<<"  "<<availableHeight-180-distance <<" "<<this->width()<<" "<<this->height();
    } else if (n == 3){
        //任务栏在右侧
        this->setGeometry(availableWidth-330-m-distance,availableHeight-180-distance,this->width(),this->height());
        qDebug()<<"任务栏在右侧"<<availableWidth-330-m-distance<<"  "<<availableHeight-180-distance <<" "<<this->width()<<" "<<this->height();
    }
}

/**
 * @brief updatewidget::insideTime
 * 获取时间
 * @return
 */
char *updatewidget::insideTime()
{
    qDebug()<<"Current index: "<<comboBox->currentText();
    QDateTime time = QDateTime::currentDateTime();                     //获取系统现在的时间
    QString str = time.toString("yyyy-MM-dd hh:mm:ss");                //设置显示格式
    QByteArray str2char2 = str.toLatin1(); // must
    char *nowtime = str2char2.data();
    delayTimer = new QTimer();
    delayTimer_Checker = new QTimer();
    connect(delayTimer, SIGNAL(timeout()), this, SLOT(delayTimeout()));
    connect(delayTimer_Checker, SIGNAL(timeout()), this, SLOT(delayTimeOutChecker()));
    if(comboBox->currentText() == strList.at(0)) {
        QDateTime bojb = QDateTime::fromString(str,"yyyy-MM-dd hh:mm:ss").addSecs(1800);
        QString str1 = bojb.toString("yyyy-MM-dd hh:mm:ss");
        QByteArray str2char2 = str1.toLatin1(); // must
        nowtime = str2char2.data();
        delaytime = 1800;
        delayTimer->start(delaytime * 1000);
        delayTimer_Checker->start(60 * 1000);
    } else if (comboBox->currentText() == strList.at(1)) {
        QDateTime bojb = QDateTime::fromString(str,"yyyy-MM-dd hh:mm:ss").addSecs(3600 * 3);
        QString str1 = bojb.toString("yyyy-MM-dd hh:mm:ss");
        QByteArray str2char2 = str1.toLatin1(); // must
        nowtime = str2char2.data();
        delaytime = 3600 * 3;
        delayTimer->start(delaytime * 1000);
        delayTimer_Checker->start(60 * 1000);
    }
    qDebug()<<"delay trigger for: "<<delaytime;
    return nowtime;
}

/**
 * @brief updatehandle::delayTimeout
 * 延时超时函数
 */
void updatewidget::delayTimeout()
{
    qDebug() << "delayTimeout, Redetect the update ...";
    delayTimer->stop();
    delayTimer_Checker->stop();
    QProcess p(0);
    p.startDetached("/usr/share/kylin-update-notify/checkUpdate.py");
    p.waitForStarted();
}

void updatewidget::delayTimeOutChecker()
{
    qDebug()<< qSetFieldWidth(0) << "delayTimeoutChecker remainingTime: "<<delayTimer->remainingTime()/1000<<"s";
}

/**
 * @brief updatewidget::agreeBtnClicked
 * 同意更新按钮槽函数
 */
void updatewidget::agreeBtnClicked()
{
    emit agreeBtnSignals();
//    qDebug()<<"WifiButtonClickSlot is running";
    QProcess p(0);
    p.startDetached("update-manager");
    p.waitForStarted();
    qDebug()<<"Open the control panel and start updating immediately, exit tray program!";
    this->hide();
}

/**
 * @brief updatewidget::disAgreeBtnClicked
 * 延迟提醒按钮槽函数
 */
void updatewidget::disAgreeBtnClicked()
{
    //判断是否有kylin-background-upgrade目录，没有则创建
    QString toDir = QDir::homePath();
    toDir += "/.config/kylin-background-upgrade/";
    QDir dir(toDir);
    if(! dir.exists()) {
       dir.mkdir(toDir);//只创建一级子目录，即必须保证上级目录存在
    }

    toDir += "kylin-background-upgrade-conf.ini";
    QFileInfo fileInfo(toDir);
    if (!fileInfo.exists()) {
       qDebug()<<"The periodic configuration file fails to be opened, exit!";
       exit(0);
    } else {
        char *nowtime=insideTime();
        qDebug() << "nowtime "<<nowtime;
        timersettings = new QSettings(toDir,QSettings::IniFormat);
        timersettings->beginGroup(QString::fromLocal8Bit("Timer"));
        timersettings->setValue("CheckUpgradeTime",nowtime);
        timersettings->sync();
        timersettings->endGroup();
    }
    emit disAgreeBtnSignals();
    qDebug()<<"Delay updating the system.";
//    exit(0);
}

/**
 * @brief updatewidget::paintEvent
 * 样式绘画画家
 * @param e
 */
void updatewidget::paintEvent(QPaintEvent *e)
{
    QStyleOption opt;
    opt.init(this);
    QPainter p(this);
    /* 获取当前剪贴板中字体的颜色，作为背景色；
     * 白字体 --> 黑背景
     * 黑字体 --> 白字体
    */
    p.setBrush(opt.palette.color(QPalette::Base));
    p.setOpacity(1);
    p.setPen(QPen(QColor(220,220,220)));
    QPainterPath path;
    opt.rect.adjust(0,0,0,0);
    path.addRoundedRect(opt.rect,12,12);
    p.setRenderHint(QPainter::Antialiasing);                        //反锯齿
    p.drawRoundedRect(opt.rect,12,12);
    setProperty("blurRegion",QRegion(path.toFillPolygon().toPolygon()));
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
    QWidget::paintEvent(e);
}

/**
 * @brief updateTip::updateTip
 * 提示框
 * @param parent
 */
updateTip::updateTip(QWidget *parent) :
    QWidget(parent)
{
    //设置任务栏无显示
    setWindowFlags(Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint);
    setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint | Qt::Popup);

    m_layout = new QVBoxLayout();
    tipLabel = new QLabel();
    tipLabel->setText(tr("The system is updating silently"));
    m_layout->addWidget(tipLabel);
    this->setLayout(m_layout);
    this->setAttribute(Qt::WA_TranslucentBackground);
}

updateTip::~updateTip()
{

}

/**
 * @brief updateTip::paintEvent
 * 样式绘画画家
 * @param e
 */
void updateTip::paintEvent(QPaintEvent *e)
{
    QStyleOption opt;
    opt.init(this);
    QPainter p(this);
    /* 获取当前剪贴板中字体的颜色，作为背景色；
     * 白字体 --> 黑背景
     * 黑字体 --> 白字体
    */
    p.setBrush(opt.palette.color(QPalette::Base));
    p.setOpacity(1);
    p.setPen(QPen(QColor(220,220,220)));
    QPainterPath path;
    opt.rect.adjust(0,0,0,0);
    path.addRoundedRect(opt.rect,4,4);
    p.setRenderHint(QPainter::Antialiasing);                        //反锯齿
    p.drawRoundedRect(opt.rect,4,4);
    setProperty("blurRegion",QRegion(path.toFillPolygon().toPolygon()));
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
    QWidget::paintEvent(e);
}

